require "Common/define"
require "Logic/Config"
require "Common/functions"
---@class MythicDungeonsManager
MythicDungeonsManager = {};
local this = MythicDungeonsManager;

local lastLayer = nil
local maxLayer = 1;   -- 通关最高关卡
local currentLayer = 1; --当前关卡
local selectLayer = 1
local formationInfos = {}; --阵容信息 （1：敌队1 2：敌队2 3：我队1 4：我队2）
local selectedBuffId = {};    -- 生效的Buff
local waitBuffIds = {};  -- 待选buff

local roundInfos = {};  -- 战斗结果存储
local itemInfos = {};  -- 战斗奖励存储
local battleTime = 0;--最近一次战斗时间
local taskCfg = {};
local currentPingfen = nil
local rushWards = {}

--- @param data table<number, FighterMemberInfo>
local showLiveHeroData = {}; -- 显示的我方阵容信息{1：一队信息{{state：0存活 1死亡 ,data}..},2:二队信息..}
local showLiveEnemyData = {}; -- 显示的敌方阵容信息{1：一队信息{{state：0存活 1死亡 ,data}..},2:二队信息..}

function MythicDungeonsManager.init()
    maxLayer = 0;
    currentLayer = 0;
    currentPingfen = 0
    selectLayer = 0
    selectedBuffId = {};
    waitBuffIds = {};
    roundInfos = {};
    formationInfos = {};
    itemInfos = {};
    --ranks:table<number, TowerRankInfo>
    this.rankList = { ranks = {}, myRank = {} } --排行榜数据
    this.rankVersion = 0 --排行榜版本号
end

function MythicDungeonsManager.setInfo(msg)
    lastLayer = msg.lastLayerId
    maxLayer = msg.layerId;
    currentLayer = msg.currLayerId;
    selectLayer = msg.currLayerId
    currentPingfen = msg.lastLayerIdLevel
    itemInfos = {};
    local formationIds = {};
    for i = 1, #msg.formations do
        formationIds[msg.formations[i].round] = {};
        for k = 1, #msg.formations[i].formation do
            formationIds[msg.formations[i].round][k] = tostring(msg.formations[i].formation[k]);
        end
    end
    logicMgr.FormationManager.SetFormation(EnumConst.FormationType.MythicDungeons, formationIds);

    TAManager.UserSet("current_mythic_rank", currentLayer) 
end

function MythicDungeonsManager.setLayer(msg)
    currentLayer = msg.layerId;
    selectLayer = msg.layerId
    waitBuffIds = msg.buffs;
    selectedBuffId = {};
    formationInfos = msg.teamInfos;
    itemInfos = {};
end
--扫荡奖励
function MythicDungeonsManager.RushWards(msg)
    rushWards = msg
end

function MythicDungeonsManager.GetRushWards()
    local items = {}
    items["items"] = {}
    for _,v in pairs(rushWards) do
        for _,ward in pairs(v.items) do
            if #items["items"] > 0 then
                local isInsert = false
                for _,val in pairs(items["items"]) do
                    if val and val.itemModelId== ward.itemModelId then
                        isInsert = true
                        val.num = val.num +ward.num
                    end
                end
                if not isInsert then
                    table.insert(items["items"],clone(ward))
                end
            else
                table.insert(items["items"],clone(ward))
            end
        end
    end
    table.insert(rushWards,items)
    return rushWards
end

function MythicDungeonsManager.AddLayer()
    if maxLayer < currentLayer then
        maxLayer = currentLayer;
    end
end

function MythicDungeonsManager.setBattleTime(time)
    battleTime = time;
end

function MythicDungeonsManager.setBattleRes(msg)

    roundInfos = {};
    for i = 1, #msg.battleResult do
        roundInfos[i] = {};
        roundInfos[i].layer = currentLayer;
        roundInfos[i].round = msg.battleResult[i].round;
        roundInfos[i].fightId = msg.battleResult[i].fightId;
        roundInfos[i].result = msg.battleResult[i].win;
        roundInfos[i].maxLayer = maxLayer
        roundInfos[i].buffId = selectedBuffId.buffId
    end
    itemInfos = msg.items;
    lastLayer = currentLayer
    currentLayer = 0;
    selectedBuffId = {};
    formationInfos = {};
    waitBuffIds = {};
end
function MythicDungeonsManager.GetLayerMapName()
    local cfg = dataTable.getDataTableByStringId("t_mythicdungeons", selectLayer)
    if cfg == nil then
        logError("找不到t_mythicdungeons  id：" .. selectLayer)
    end
    local mapList = decodeJsonStrToTabel(cfg.f_BattleMap)
    local index = math.random(1, #mapList)
    return mapList[index]
end
function MythicDungeonsManager.setBuff(id)
    selectedBuffId = id;
end
function MythicDungeonsManager.GetSelectLayer()
    return selectLayer
end
function MythicDungeonsManager.setWaitBuffs(msg)
    waitBuffIds = msg.buffId;
end

function MythicDungeonsManager.getLayer()
    return currentLayer;
end

function MythicDungeonsManager.SetLayerLevel(level)
    currentPingfen = level
end

function MythicDungeonsManager.getLayerLevel()
    return currentPingfen
end

function MythicDungeonsManager.getMaxLayer()
    return maxLayer;
end

function MythicDungeonsManager.LastLayer()
    return lastLayer
end

function MythicDungeonsManager.getFormationInfos()
    return clone(formationInfos);
end

function MythicDungeonsManager.getSelectedBuffId()
    return selectedBuffId;
end

function MythicDungeonsManager.getWaitBuffIds()
    return clone(waitBuffIds);
end

function MythicDungeonsManager.getRoundInfos()
    return clone(roundInfos);
end

function MythicDungeonsManager.getItemInfos()
    return clone(itemInfos);
end

function MythicDungeonsManager.getBattleTime()
    return battleTime;
end

function MythicDungeonsManager.getRedPoint()
    if logicMgr.ItemManager.getCurrencyCountByModelId(CurrencyEnum.MythicDungoesTicket) > 0 then
        return true;
    end
    return false;
end

function MythicDungeonsManager.checkTaskCfgById(layer)
    if table.getn(taskCfg) == 0 then
        local cfg = G.dataTable["t_task"];
        for k, v in pairs(cfg) do
            if v.f_TaskType == 8005 then
                table.insert(taskCfg, v);
            end
        end
        table.sort(taskCfg, function(a, b)
            return a.f_TaskId < b.f_TaskId;
        end)
    end
    for i = 1, #taskCfg do
        if #taskCfg >= i + 1 then
            if i == 1 and layer < taskCfg[i].f_Progress then
                return taskCfg[i];
            end
            if taskCfg[i].f_Progress <= layer and taskCfg[i + 1].f_Progress > layer then
                return taskCfg[i + 1];
            end
        else
            return false;
        end

    end
end
---@param ranks TowerRankInfo
function MythicDungeonsManager.SetRanks(ranks)
    MythicDungeonsManager.rankList.ranks = clone(ranks)
end
function MythicDungeonsManager.SetMyRank(myRank, myScore)
    MythicDungeonsManager.rankList.myRank = {
        rank = myRank,
        score = myScore
    }
end
--[[
    teamType 1 第一队 2 第二队
    teamIdx 1 己方队伍 2敌方队伍
]]
function MythicDungeonsManager.GetBattleFormations(teamIdx)
    if BattlePlaybackManager.GetFightIndex() == 2 and not this.initTeam2 then
        local DeadList = FightManager.deadFormation[1] or {}
        for i, j in pairs(DeadList) do
            for k, v in pairs(showLiveHeroData[1]) do
                if j.partnerModelId == tostring(v.data.partnerModelId) and j.teamIndex == 1 then
                    v.state = 1;
                end
            end
            for k, v in pairs(showLiveEnemyData[1]) do
                if j.partnerModelId == tostring(v.data.partnerModelId) and j.teamIndex == 2 then
                    v.state = 1;
                end
            end
        end
        this.initTeam2 = true;
    end
    if BattlePlaybackManager.GetFightIndex() == 3 then
        local DeadList = FightManager.deadFormation[2] or {}
        for i, j in pairs(DeadList) do
            for k, v in pairs(showLiveHeroData[2]) do
                if j.partnerModelId ==  tostring(v.data.partnerModelId) and j.teamIndex == 1 then
                    v.state = 1;
                end
            end
            for k, v in pairs(showLiveEnemyData[2]) do
                if j.partnerModelId ==  tostring(v.data.partnerModelId) and j.teamIndex == 2 then
                    v.state = 1;
                end
            end
        end
    end

    if teamIdx == 1 then
        return showLiveHeroData;
    else
        return showLiveEnemyData;
    end
end

--- @param data table<number, FighterMemberInfo>
--[[
    teamType 1 第一队 2 第二队
    teamIdx 1 己方队伍 2敌方队伍
]]
function MythicDungeonsManager.SetBattleFormations(data, teamIdx, teamType)
    this.initTeam2 = false;
    this.initTeam3 = false;

    if teamIdx == 1 then
        if showLiveHeroData[teamType] == nil then
            showLiveHeroData[teamType] = {};
        end
        for i = 1, #data do
            local heroInfo = data[i];
            local param = {}
            param.state = 0;
            param.data = heroInfo;
            table.insert(showLiveHeroData[teamType], param)
        end
    else
        if showLiveEnemyData[teamType] == nil then
            showLiveEnemyData[teamType] = {};
        end
        for i = 1, #data do
            local heroInfo = data[i];
            local param = {}
            param.state = 0;
            param.data = heroInfo;
            table.insert(showLiveEnemyData[teamType], param)
        end
    end
end
--teamType队伍类型 1 一队 2 二队
--data{ id = 死亡英雄modelId, teamId = 英雄队伍id }
function MythicDungeonsManager.heroDeadShow(data, teamType)
    if data.teamId == 1 then
        if showLiveHeroData and showLiveHeroData[teamType] then
            for k, v in pairs(showLiveHeroData[teamType]) do
                if v.data.partnerModelId == tonumber(data.id) then
                    showLiveHeroData[teamType][k].state = 1;
                    return ;
                end
            end
        end
    else
        if showLiveEnemyData and showLiveEnemyData[teamType] then
            for k, v in pairs(showLiveEnemyData[teamType]) do
                --敌方阵容会出现重复英雄 此处要判断同名英雄是否存活
                if v.data.partnerModelId == tonumber(data.id) and showLiveEnemyData[teamType][k].state == 0 then
                    showLiveEnemyData[teamType][k].state = 1;
                    return ;
                end
            end
        end

    end
end

function MythicDungeonsManager.ClearShowList()
    showLiveEnemyData = {}
    showLiveHeroData = {}
    FightManager.deadFormation = {};
end

return MythicDungeonsManager